import { profile } from '@/utils/decorators';
import { guardObj } from '@/utils/functions/safeAccesss';
import { NormalColony } from '../../NormalColony';

const $ = Game.getObjectById;   // 临时简写

const findAsId = <T extends _HasId>(arr: T[], predicate: (obj: T) => boolean) => {
    const target = arr.find(predicate);
    return target ? target.id : undefined;
}

export class StructureDistributeManager {

    readonly colony: NormalColony;

    constructor(colony: NormalColony) {
        this.colony = colony;
    }

    get room() {
        return this.colony.capital;
    }

    get memory() {
        return guardObj(this.room.memory, 'distribute', {});
    }

    @profile
    update() {
        /**
         * 布局
         * S e e e S
         * e   e   e
         * c e l e c
         * e   e   e
         * e e S e e
         */
        // nullish check
        if (!this.room) {
            return;
        }
        // 更新 spawn 信息
        const spawns = this.room.getSpawns().sort((a, b) => a.pos.x - b.pos.x);
        const topLeftSpawn = spawns[0];
        this.memory.spawn0 = (spawns[0] || {}).id;
        this.memory.spawn1 = (spawns[1] || {}).id;
        this.memory.spawn2 = (spawns[2] || {}).id;
        // 更新 hatchery battery
        const containers = this.room.getContainers();
        if (topLeftSpawn) {
            this.memory.leftBattery = findAsId(containers, c =>
                c.pos.x === topLeftSpawn.pos.x && c.pos.y === topLeftSpawn.pos.y + 2
            );
            this.memory.rightBattery = findAsId(containers, c =>
                c.pos.x === topLeftSpawn.pos.x + 4 && c.pos.y === topLeftSpawn.pos.y + 2
            );
        }
        // 更新 fast fill extension
        if (topLeftSpawn) {
            const extensions = this.room.getExtensions();
            this.memory.fastFillExts = extensions
                .filter(e => e.pos.x <= topLeftSpawn.pos.x + 4 && e.pos.y <= topLeftSpawn.pos.y + 4)
                .map(e => e.id);
        }
        // 更新 link 网络
        const links = this.room.getLinks();
        if (topLeftSpawn) {
            this.memory.centerLink = findAsId(links, l =>
                l.pos.x === topLeftSpawn.pos.x + 2 && l.pos.y === topLeftSpawn.pos.y + 2
            );
        }
        if (this.room.getStorage()) {
            const s = this.room.getStorage();
            this.memory.centerLink = findAsId(links, l =>
                l.pos.x === s.pos.x - 2 && l.pos.y === s.pos.y
            );
        }
        this.memory.upgradeLink = findAsId(links, l =>
            l.pos.inRangeTo(this.room.getController(), 2)
        );
        this.memory.sourceLinks = links.filter(l => {
            return l.pos.findInRange(FIND_SOURCES, 2).length > 0
        }).map(l => l.id);
        // 更新 tower
        if (!this.memory.commonTower) {
            const tower = this.room.getTowers()[0];
            this.memory.commonTower = tower ? tower.id : undefined;
        }
    }

    /**
     * 获取特定的 spawn
     */
    getSpawn(index: 0 | 1 | 2) {
        if (index === 0) {
            return $(this.memory.spawn0);
        }
        else if (index === 1) {
            return $(this.memory.spawn1);
        }
        else if (index === 2) {
            return $(this.memory.spawn2);
        }
    }

    getHatcheryBatteries() {
        return this.getHatcheryBattery() as StructureContainer[];
    }

    getHatcheryBattery(where: 'left' | 'right' | void) {
        if (where === undefined) {
            return [$(this.memory.leftBattery), $(this.memory.rightBattery)].filter(Boolean);
        }
        else if (where === 'left') {
            return $(this.memory.leftBattery);
        }
        else {
            return $(this.memory.rightBattery);
        }
    }

    getFastFillExtensions() {
        return (this.memory.fastFillExts || []).map(id => $(id));
    }

    isFastFillExtension(extension: StructureExtension) {
        return (this.memory.fastFillExts || []).includes(extension.id);
    }

    getLinkOf(type: 'hatchery' | 'center' | 'upgrade' | 'source') {
        if (type === 'hatchery') {
            return $(this.memory.hatcheryLink);
        }
        else if (type === 'center') {
            return $(this.memory.centerLink);
        }
        else if (type === 'upgrade') {
            return $(this.memory.centerLink);
        }
        else if (type === 'source') {
            return (this.memory.sourceLinks || []).map(id => $(id));
        }
    }

    getCommonTower() {
        return $(this.memory.commonTower);
    }

}
